package com.github.szhittech.service.api;


import com.github.szhittech.bean.ClassBean;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class ApiService {
    private static HashMap<Class<?>, ClassBean<?>> serviceConfig = new HashMap<>();

    public static <T> void registerService(Class<T> paramClass, ClassBean<?> classBean) {
        serviceConfig.put(paramClass, classBean);
    }

    public static <T> void registerService(Class<T> paramClass, Class<?> paramClassImpl) {
        serviceConfig.put(paramClass, new ClassBean(paramClassImpl));
    }

    public static <T> void registerService(Map<Class<?>, ClassBean<?>> maps) {
        serviceConfig.putAll(maps);
    }

    public static <T> ClassBean<T> getServiceImplementClass(Class<T> paramClass) {
        return (ClassBean<T>) serviceConfig.get(paramClass);
    }

    public static <T> T getInstance(Class<T> tClass) {
        ClassBean<T> cls = getServiceImplementClass(tClass);
        if (cls != null) {
            try {
                return (T) newObject(getConstructor(cls.getClazz(), cls.getParamTypes()), cls.getArgs());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    private static Constructor<?> getConstructor(Class cls, Class<?>... parameterTypes) throws ClassNotFoundException, NoSuchMethodException {
        Class<?> clasz = Class.forName(cls.getName());
        Constructor<?> cons = clasz.getConstructor(parameterTypes);
        return cons;
    }

    private static Constructor<?> getConstructor(String packageName, Class<?>... parameterTypes) throws ClassNotFoundException, NoSuchMethodException {
        Class<?> clasz = Class.forName(packageName);
        Constructor<?> cons = clasz.getConstructor(parameterTypes);
        return cons;
    }

    private static Object newObject(Constructor<?> constructor, Object... initargs) throws IllegalAccessException, InvocationTargetException, InstantiationException {
        return constructor.newInstance(initargs);
    }
}
